#ifndef RENDER_MANAGER_H_
#define RENDER_MANAGER_H_

// INCLUDES //
#include "SDL/SDL.h"
#include "object.h"
#include "graphics/graphics.h"
#include "graphics/screen.h"
#include "graphics/surface.h"
#include <vector>
//////////////

/**
* Represents a custom render request.
* 
* @author dfoelber
**/
class CustomRender
{
public:
	enum RenderType
	{
		TYPE_NONE = 0,
		TYPE_IMAGE,
		TYPE_FONT,
		TYPE_RECT
	};
	
	CustomRender() {type = TYPE_NONE;}
public:
	RenderType type;
	int x;
	int y;
	int width;
	int height;
};

/**
* Represents a custom render request involving the painting of an rectangle.
* 
* @author dfoelber
**/
class RectCustomRender : public CustomRender
{
public:
	RectCustomRender() {type = TYPE_RECT;}
	Color color;
	bool fill;
};

/**
* Represents a custom render request involving the painting of an image.
* 
* @author dfoelber
**/
class ImageCustomRender : public CustomRender
{
public:
	ImageCustomRender() {type = TYPE_IMAGE;}
	Surface* surface;
};

/**
* Represents a custom render request involving the drawing of a font.
* 
* @author dfoelber
**/
class FontCustomRender : public CustomRender
{
public:
	FontCustomRender() 
	{
		type = TYPE_FONT; 
		alpha = 255; 
		alignment = ALIGNMENT_LEFT | ALIGNMENT_TOP;
	}
	
	Font font;
	string str;
	int size;
	Color color;
	int alpha;
	Uint8 alignment;
};

/**
* Handles the global drawing of objects on the screen.
* 
* @author dfoelber
**/
class RenderManager
{
public:
	/**
	* Singleton accessor
	* 
	* @return Singleton instance
	**/
	static RenderManager* GetManager();
	
	/**
	* Deconstructor
	**/
	~RenderManager();
	
	/**
	* Loads the screen
	* 
	* @param screen The screen
	**/
	void LoadScreen(Screen* screen);
	
	/**
	* Loads the background and paints it to the screen
	* 
	* @param surface The background surface
	**/
	void LoadBackground(Surface* surface);
	
	/**
	* Performs a render pass
	**/
	void Render();
	
	/**
	* Adds an object to render
	* 
	* @param object The object
	**/
	void AddObject( Object* object );
	
	/**
	* Removes an object from the render list
	* 
	* @param object The object
	**/
	void RemoveObject( Object* object );
	
	/**
	* Adds a custom render request, good for one render pass.
	* 
	* @param custom The custom render request
	**/
	void AddCustomRender( CustomRender* custom );
	
private:
	/**
	* Private constructor
	**/
	RenderManager();
	
	/**
	* Helper function to (possibly) add another rectangle to update.
	**/
	void AddToUpdateRectangles(SDL_Rect* rects, int* currentSize, int x, int y, int width, int height);
	
	/**
	* Render a custom render of the image type.
	**/
	void ApplyCustomImageRender(ImageCustomRender* render);
	
	/**
	* Render a custom render of the font type.
	**/
	void ApplyCustomFontRender(FontCustomRender* render);
	
	/**
	* Render a custom render of the rect type.
	**/
	void ApplyCustomRectRender(RectCustomRender* render);
	
private:
	/**
	* Singleton instance
	**/
	static RenderManager* 			instance;
	
	/**
	* The screen
	*/
	Screen*							screen;
	
	/**
	* The background
	*/
	Surface*						background;
	
	/**
	* List of dirty rectangles
	*/
	vector<SDL_Rect*>				dirty;
	
	/**
	* List of objects to render
	*/
	vector<Object*>					objects;
	
	/** 
	* List of custom renders
	*/
	vector<CustomRender*>			customs;
};

#endif /*RENDER_MANAGER_H_*/
